package middleware

import (
	"TD-UI/internal/consts/enums"
	"TD-UI/internal/service"
	"TD-UI/utility/response"
	"errors"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/i18n/gi18n"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/util/gutil"
	"github.com/gogf/gf/v2/util/gvalid"
	"net/http"
	"reflect"
)

type sMiddleware struct{}

func init() {
	service.RegisterMiddleware(New())
}

func New() service.IMiddleware {
	return &sMiddleware{}
}

func (s *sMiddleware) CORSHandler(r *ghttp.Request) {
	r.Response.CORSDefault()
	r.Middleware.Next()
}

func (s *sMiddleware) I18NHandler(r *ghttp.Request) {
	r.SetCtx(gi18n.WithLanguage(r.Context(), r.Header.Get("language")))
	r.Middleware.Next()
}

func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
	r.Middleware.Next()
	err := r.GetError()
	if err == nil {
		return
	}
	glog.Error(r.GetCtx(), err)
	r.Response.ClearBuffer()
	var gvalidErr gvalid.Error
	errors.As(err, &gvalidErr)
	r.Response.Status = http.StatusOK
	if !gutil.IsEmpty(gvalidErr) {
		rule, err := gvalidErr.FirstRule()
		if "required" == rule {
			response.Json(
				r, enums.New(enums.IllegalArgument.Code(), err.Error()),
				nil,
			)
		} else {
			response.Json(
				r, enums.New(enums.RequestParamTypeError.Code(), err.Error()),
				nil,
			)
		}
	} else if reflect.TypeOf(err.(gerror.ICode).Code()).Name() == reflect.TypeOf(enums.OpenResponseEnum{}).Name() {
		response.Json(r, err.(gerror.ICode).Code(), nil)
	} else {
		r.Response.Status = http.StatusInternalServerError
		response.FailMsg(r)
	}
}

func (s *sMiddleware) ErrorHandler(r *ghttp.Request) {
	r.Middleware.Next()
	// 如果已经有返回内容，那么该中间件什么也不做
	if r.Response.BufferLength() > 0 {
		return
	}
	var (
		err  = r.GetError()
		res  = r.GetHandlerResponse()
		code = gerror.Code(err)
	)
	if err != nil {
		if code == gcode.CodeNil {
			code = enums.Fail
		}
		response.JsonExit(r, code, nil)
	} else {
		response.SuccessMsg(r, res)
	}
}
